package com.biodiv.miracle.aop.proxy;

import com.biodiv.miracle.aop.JoinPintImpl;

import java.lang.reflect.Method;
import java.util.List;

/**
 * @Author: tianquan
 * @CreateTime: 2025-05-25  12:26
 * @Description: 公共方法调用
 */
public abstract class AbstractMethodInvocation implements MethodInvocation{

    /**
     * 需要代理的对象
     */
    protected Object object;

    /**
     * 需要代理的所有方法名称列表
     */
    protected List<String> objectMethodName;

    /**
     * 前置增强方法
     */
    protected Method beforeMethod;

    /**
     * 后置增强方法
     */
    protected Method afterMethod;

    /**
     * 用来调用对应方法的类
     */
    protected Object target;

    /**
     * 环绕增强方法
     */
    protected Method aroundMethod;

    /**
     * 拦截方法调用，根据方法名称和是否存在增强方法来决定执行流程
     *
     * @param proxy           代理对象
     * @param method      被调用的方法对象
     * @param objects     方法参数
     * @return 方法调用的结果
     * @throws Throwable 如果方法调用过程中出现异常
     */
    public Object invokeMethod(Object proxy, Method method, Object[] objects) throws Throwable {
        // 如果不是需要代理的方法，则直接调用
        if (!objectMethodName.contains(method.getName())) {
            return method.invoke(this.object, objects);
        }
        Object invoke;
        // 调用前置增强方法
        if (beforeMethod != null) {
            invoke = beforeMethod.invoke(target);
        }
        // 是否有环绕通知
        if (aroundMethod != null) {
            invoke = aroundMethod.invoke(target, new JoinPintImpl(this.object, method, objects));
        } else {
            // 通过反射调用代理类的方法
            invoke = method.invoke(this.object, objects);
        }
        // 调用后置增强方法
        if (afterMethod != null) {
            invoke = afterMethod.invoke(target);
        }
        return invoke;
    }

}
